package in.co.codedoc.sql;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

public class IDBase
	implements Comparable<IDBase>
{
	protected IDBase(long id)
	{
		this.id = id;
	}

	protected IDBase Intern()
	{
		synchronized (internedInstances)
		{
			WeakReference<IDBase> rtnRef = internedInstances.get(this);

			IDBase rtn = rtnRef != null ? rtnRef.get() : null;

			if (rtn == null)
			{
				rtn = this;
				internedInstances.put(this, new WeakReference<IDBase>(this));

				maxSize++;

				int size = internedInstances.size();

				if (size > maxSize) {
					maxSize = size;
				}

				if (((maxSize / size) > 4) && (maxSize > maxAllowedSize))
				{
					WeakHashMap<IDBase,WeakReference<IDBase>> tmp 
						= new WeakHashMap<IDBase,WeakReference<IDBase>>(size);

					tmp.putAll(internedInstances);
					internedInstances = tmp;
					maxSize = size;
				}
			}

			return rtn;
		}
	}

	public boolean equals(Object obj)
	{
		if (this == obj) {
			return true;
		}

		if (obj == null) {
			return false;
		}

		if (this.getClass() != obj.getClass()) {
			return false;
		}

		IDBase other = (IDBase) obj;

		return id == other.id;
	}

	public int hashCode()
	{
		return classHashCode ^ ((int)id) ^ ((int)(id >> 32));
	}

	public String toString()
	{
		return Long.toString(id);
	}

	public long GetId()
	{
		return id;
	}

	public int compareTo(IDBase o)
	{
		if ((o == null))
		{
			return -1;
		}

		if (o == this) {
			return 0;
		}

		return id < o.id ? -1 : (id == o.id ? 0 : +1);
	}

	private static WeakHashMap<IDBase,WeakReference<IDBase>> internedInstances 
		= new WeakHashMap<IDBase,WeakReference<IDBase>>();
	
	private static int maxSize = 0;

	private static int maxAllowedSize = 1 << 22;

	private static int classHashCode = IDBase.class.hashCode();
	
	private long id;	
}
